home *** CD-ROM | disk | FTP | other *** search
Wrap
#include <proto/dos.h> #include <stdio.h> #include <errno.h> #include <ctype.h> #include <Amiga.h> /************************************************************************/ char VersionString[]="$VER: AsmStub 1.0 (17.04.95)© 1995 Christian Stieber"; /************************************************************************/ #define REGISTER_COUNT 15 #define REGISTER_A4 12 static struct { long Registers[REGISTER_COUNT]; long Saveds; long Static; long Interrupt; long InterruptBug; } Arguments; static int RegisterCount; static const char *RegisterName[REGISTER_COUNT]= { "d0","d1","d2","d3","d4","d5","d6","d7", "a0","a1","a2","a3","a4","a5","a6" }; static int RC; /************************************************************************/ static void OutputMacroName(int Prototype) { int Register; int Underscore; Underscore=FALSE; if (Arguments.Static) { printf("STATIC"); Underscore=TRUE; } if (Arguments.Saveds) { if (Underscore) { printf("_"); } printf("SAVEDS"); Underscore=TRUE; } if (Arguments.Interrupt) { if (Underscore) { printf("_"); } printf("INTERRUPT"); if (Arguments.InterruptBug) { printf("BUG"); } Underscore=TRUE; } if (RegisterCount!=0) { if (Underscore) { printf("_"); } printf("ASM_"); for (Register=0; Register<REGISTER_COUNT; Register++) { if (Arguments.Registers[Register]) { const char *t; for (t=RegisterName[Register]; *t; t++) { printf("%lc",(long)toupper(*t)); } } } Underscore=TRUE; } if (Prototype) { if (Underscore) { printf("_"); } printf("PROTO"); } printf("(ReturnType,FuncName"); for (Register=0; Register<REGISTER_COUNT; Register++) { if (Arguments.Registers[Register]) { printf(",%sType",RegisterName[Register]); if (!Prototype) { printf(",%sName",RegisterName[Register]); } } } printf(")"); } /************************************************************************/ static void CreateSAS5Macros(void) { int Prototype; printf("#ifdef __SASC\n"); for (Prototype=1; Prototype>=0; Prototype--) { printf("#define "); OutputMacroName(Prototype); if (Arguments.Static) { printf(" static"); } printf(" ReturnType "); if (Arguments.Saveds) { printf("__SAVEDS "); } if (Arguments.Interrupt) { printf("interrupt_not_implemented "); } if (RegisterCount!=0) { int Register; int Count; printf("__asm FuncName("); Count=0; for (Register=0; Register<REGISTER_COUNT; Register++) { if (Arguments.Registers[Register]) { if (Count!=0) { printf(", "); } printf("register __%s %sType",RegisterName[Register],RegisterName[Register]); if (!Prototype) { printf(" %sName",RegisterName[Register]); } Count++; } } printf(")\n"); } else { printf("FuncName(void)\n"); } } printf("#endif /* __SASC */\n"); } /************************************************************************/ #define MODEL_SMALLCODE (1<<0) #define MODEL_SMALLDATA (1<<1) static INLINE void GNUCCall(int AdressingType, const char *FuncName) { if (AdressingType&MODEL_SMALLCODE) { printf("\tjsr PC@(%s+2)\n",FuncName); } else { printf("\tjsr %s\n",FuncName); } } /*----------------------------------------------------------------------*/ static void GNUCOutputFunctionHeader(const char *Name) { int Register; int Count; printf("ReturnType %s(",Name); Count=0; for (Register=0; Register<REGISTER_COUNT; Register++) { if (Arguments.Registers[Register]) { if (Count!=0) { printf(", "); } printf("%sType %sName",RegisterName[Register],RegisterName[Register]); Count++; } } if (Count==0) { printf("void"); } printf(")\n"); } /*----------------------------------------------------------------------*/ static void CreateGNUCMacros(void) { int AdressingType; printf("#ifdef __GNUC__\n"); for (AdressingType=MODEL_SMALLCODE|MODEL_SMALLDATA; AdressingType>=0; AdressingType--) { int Prototype; printf("#if "); if (!(AdressingType&MODEL_SMALLDATA)) { printf("!"); } printf("defined(SMALL_DATA) && "); if (!(AdressingType&MODEL_SMALLCODE)) { printf("!"); } printf("defined(SMALL_CODE)\n"); for (Prototype=1; Prototype>=0; Prototype--) { printf("#define "); OutputMacroName(Prototype); if (Prototype) { if (Arguments.Static) { printf(" static"); } printf(" ReturnType FuncName(void)\n"); } else { printf(" "); if ((!(AdressingType&MODEL_SMALLDATA) || !Arguments.Saveds) && RegisterCount==0 && !Arguments.Interrupt) { /* we don't need stub code */ if (Arguments.Static) { printf("static "); } GNUCOutputFunctionHeader("FuncName"); } else { OutputMacroName(TRUE); printf("; asm(\x22 .text\n"); if (!Arguments.Static) { printf("\t.globl _\x22 #FuncName \x22\n"); } printf("_\x22 #FuncName \x22:\n"); if ((!(AdressingType&MODEL_SMALLDATA) || !Arguments.Saveds) && RegisterCount==0) { GNUCCall(AdressingType,"___AsmEntry\x22 #FuncName \x22"); } else if (Arguments.Saveds && (RegisterCount==0 || (RegisterCount==1 && Arguments.Registers[REGISTER_A4]))) { if (Arguments.Interrupt && RegisterCount==0) { /* I'm using a5, since using a6 would make it unusable for softints */ printf("\tmovl a4,a5\n"); } else { printf("\tmovl a4,SP@-\n"); } if (AdressingType&MODEL_SMALLDATA) { GNUCCall(AdressingType,"__geta4"); } GNUCCall(AdressingType,"___AsmEntry\x22 #FuncName \x22"); if (Arguments.Interrupt && RegisterCount==0) { printf("\tmovl a5,a4\n"); } else { if (AdressingType&MODEL_SMALLDATA) { printf("\tmovl SP@+,a4\n"); } else { printf("\taddql #4,SP\n"); } } } else if (RegisterCount==1 && (!(AdressingType&MODEL_SMALLDATA) || !Arguments.Saveds)) { int Register; for (Register=REGISTER_COUNT-1; !Arguments.Registers[Register]; Register--) ; printf("\tmovl %s,SP@-\n",RegisterName[Register]); GNUCCall(AdressingType,"___AsmEntry\x22 #FuncName \x22"); printf("\taddql #4,SP\n"); } else /* RegisterCount>1 */ { int Count; int Register; int PreA4, PostA4; int RealRegisterCount; printf("\tmovml "); Count=0; PreA4=PostA4=0; RealRegisterCount=0; for (Register=0; Register<REGISTER_COUNT; Register++) { if (Arguments.Registers[Register]) { if (Count!=0) { printf("/"); } printf(RegisterName[Register]); Count++; if (Register<REGISTER_A4) { PreA4++; } else if (Register>REGISTER_A4) { PostA4++; } RealRegisterCount++; } } if (Arguments.Saveds && (AdressingType&MODEL_SMALLDATA) && !Arguments.Registers[REGISTER_A4]) { printf("/a4"); RealRegisterCount++; } printf(",SP@-\n"); if (Arguments.Saveds && (AdressingType&MODEL_SMALLDATA)) { GNUCCall(AdressingType,"__geta4"); } GNUCCall(AdressingType,"___AsmEntry\x22 #FuncName \x22"); if (PostA4==0) { if (Arguments.Saveds && (AdressingType&MODEL_SMALLDATA)) { RealRegisterCount--; } if (RealRegisterCount<=2) { printf("\taddql #%ld,SP\n",(long)(RealRegisterCount*4)); } else { printf("\tlea SP@(%ld),SP\n",(long)(RealRegisterCount*4)); } if (Arguments.Saveds && (AdressingType&MODEL_SMALLDATA)) { printf("\tmovl SP@+,a4\n"); } } else /* PostA4 != 0 */ { if (Arguments.Saveds && (AdressingType&MODEL_SMALLDATA)) { if (PreA4==0) { if (PostA4==1) { printf("\tmovl SP@,a4\n"); printf("\taddql #8,SP\n"); } else /* (PostA4==2) */ { printf("\tmovl SP@+,a4\n"); printf("\taddql #8,SP\n"); } } else /* PreA4!=0 */ { printf("\tmovl SP@(%ld),a4\n",(long)(PreA4*4)); printf("\tlea SP@(%ld),SP\n",(long)(RealRegisterCount*4)); } } else { if (RealRegisterCount<=2) { printf("\taddql #%ld,SP\n",(long)(RealRegisterCount*4)); } else { printf("\tlea SP@(%ld),SP\n",(long)(RealRegisterCount*4)); } } } } if (Arguments.Interrupt) { if (Arguments.InterruptBug) { printf("\tmovl #$00dff000,a0\n"); } printf("\ttstl d0\n"); } printf("\trts\x22); static "); GNUCOutputFunctionHeader("__AsmEntry##FuncName"); } } } printf("#endif /* "); if (!(AdressingType&MODEL_SMALLDATA)) { printf("!"); } printf("defined(SMALL_DATA) && "); if (!(AdressingType&MODEL_SMALLCODE)) { printf("!"); } printf("defined(SMALL_CODE) */\n"); } printf("#endif /* __GNUC__ */\n"); } /************************************************************************/ int AmigaMain(void) { struct RDArgs *RDArgs; RC=RETURN_OK; if (!WorkbenchMessage) { if ((RDArgs=ReadArgs("D0/S,D1/S,D2/S,D3/S,D4/S,D5/S,D6/S,D7/S,A0/S,A1/S,A2/S,A3/S,A4/S,A5/S,A6/S,SAVEDS/S,STATIC/S,INTERRUPT/S,INTERRUPTBUG/S",(long *)&Arguments,NULL))) { int Register; if (Arguments.InterruptBug) { Arguments.Interrupt=TRUE; } if (Arguments.Interrupt) { Arguments.Saveds=TRUE; } for (Register=0; Register<REGISTER_COUNT; Register++) { if (Arguments.Registers[Register]) { RegisterCount++; } } printf("/* This file was generated automatically. */\n" "/* Do not edit. */\n\n"); CreateSAS5Macros(); printf("\n"); CreateGNUCMacros(); } else { errno=IoErr(); perror(NULL); RC=RETURN_FAIL; } } else { RC=RETURN_CATASTROPHY; } return RC; }